<script setup>
import { ref, onMounted, onUnmounted, watch, nextTick } from 'vue'
import { ElMessage } from 'element-plus'
import { useUserStore } from '../stores/user'
import axios from '@/utils/axios'
import { useRouter } from 'vue-router'
import FileUploader from './FileUploader.vue'
import AudioRecorder from './AudioRecorder.vue'
import { uploadToExternalService } from '../utils/upload'
import {
  Microphone,
  Download,
  Position,
  Service,
  User,
  Loading,
  Plus,
  Picture,
  Close,
  VideoCameraFilled,
  ArrowLeft
} from '@element-plus/icons-vue'

const userStore = useUserStore()
const messages = ref([])
const inputMessage = ref('')
const loading = ref(false)
const chatContainer = ref(null)
const pendingMessageIndex = ref(-1) // 用于跟踪思考消息的索引
const imageFile = ref(null) // 用于存储选择的图片文件
const imagePreviewUrl = ref('') // 用于存储图片预览URL
const isRecording = ref(false) // 是否正在录音
const recognition = ref(null) // 语音识别对象
const uploadedFileInfo = ref(null) // 存储上传后的文件信息

// 重试配置
const MAX_RETRIES = 3
const RETRY_DELAY = 1000

// 显示音频录制器
const showAudioRecorder = ref(false);

const sendMessage = async (retryCount = 0) => {
  // 如果没有消息文本且没有上传文件，则不发送
  if (!inputMessage.value.trim() && !uploadedFileInfo.value) return;
  
  try {
    loading.value = true;
    const currentMessage = inputMessage.value.trim();
    
    // 创建消息对象
    const messageObj = {
      type: 'user',
      content: currentMessage,
      timestamp: new Date(),
      status: 'sending' // 添加状态标记
    };
    
    // 添加文件信息（如果有）
    if (uploadedFileInfo.value) {
      messageObj.file = uploadedFileInfo.value;
    }
    
    // 添加用户消息
    const userMessageIndex = messages.value.length;
    messages.value.push(messageObj);
    
    // 清空输入框并滚动到底部
    inputMessage.value = '';
    removeImage(); // 清除图片
    await scrollToBottom();
    
    // 添加一个临时的AI思考消息
    pendingMessageIndex.value = messages.value.length;
    messages.value.push({
      type: 'ai',
      content: '正在思考...',
      timestamp: new Date(),
      isThinking: true
    });
    await scrollToBottom();

    // 调用AI接口
    console.log('Sending message to AI:', messageObj);
    
    // 构建请求数据
    const requestData = { message: currentMessage };
    
    // 如果有文件，添加文件信息
    if (messageObj.file) {
      requestData.fileUrl = messageObj.file.fileUrl;
      requestData.fileType = messageObj.file.fileType;
    }
    
    const response = await axios.post('/api/ai/chat', requestData);

    console.log('AI response received:', response.data);
    
    // 更新用户消息状态
    if (messages.value[userMessageIndex]) {
      messages.value[userMessageIndex].status = 'sent';
    }
    
    // 移除临时思考消息
    messages.value = messages.value.filter(msg => !msg.isThinking);
    pendingMessageIndex.value = -1;

    if (response.data.success) {
      // 添加AI回复消息
      messages.value.push({
        type: 'ai',
        content: response.data.data.message,
        timestamp: new Date()
      });
      
      // 确保消息添加后滚动到底部
      await nextTick();
      scrollToBottom();
    } else {
      // 显示错误消息
      ElMessage.error(response.data.message || '发送消息失败');
    }
  } catch (error) {
    console.error('Chat error:', error);
    
    // 如果是超时错误并且重试次数未达到最大值，则重试
    if (error.code === 'ECONNABORTED' && retryCount < MAX_RETRIES) {
      console.log(`请求超时，正在重试 (${retryCount + 1}/${MAX_RETRIES})...`);
      
      // 移除临时思考消息
      messages.value = messages.value.filter(msg => !msg.isThinking);
      pendingMessageIndex.value = -1;
      
      // 更新用户消息状态为重试中
      const lastUserMsgIndex = [...messages.value].reverse().findIndex(msg => msg.type === 'user');
      if (lastUserMsgIndex >= 0) {
        const actualIndex = messages.value.length - 1 - lastUserMsgIndex;
        messages.value[actualIndex].status = 'retrying';
      }
      
      // 等待一段时间后重试
      setTimeout(() => {
        loading.value = false; // 重置 loading 状态
        sendMessage(retryCount + 1); // 递归调用自身进行重试
      }, RETRY_DELAY * (retryCount + 1)); // 随着重试次数增加等待时间
      
      return; // 提前返回，不执行后续错误处理
    }
    
    // 移除临时思考消息
    messages.value = messages.value.filter(msg => !msg.isThinking);
    pendingMessageIndex.value = -1;
    
    // 标记最后一条用户消息为失败
    const lastUserMsgIndex = [...messages.value].reverse().findIndex(msg => msg.type === 'user');
    if (lastUserMsgIndex >= 0) {
      const actualIndex = messages.value.length - 1 - lastUserMsgIndex;
      messages.value[actualIndex].status = 'failed';
    }
    
    // 显示错误消息
    const errorMsg = error.response?.data?.message || error.message || '发送消息失败';
    ElMessage.error(errorMsg);
    
    // 添加一个系统消息说明错误
    messages.value.push({
      type: 'system',
      content: `消息发送失败: ${errorMsg}`,
      timestamp: new Date()
    });
  } finally {
    if (loading.value) { // 只有在没有重试的情况下才重置 loading
      loading.value = false;
      await scrollToBottom();
    }
  }
};

const scrollToBottom = async () => {
  if (chatContainer.value) {
    await nextTick(); // 等待DOM更新
    chatContainer.value.scrollTop = chatContainer.value.scrollHeight;
  }
}

// 自动滚动到底部
watch(messages, () => {
  scrollToBottom();
}, { deep: true });

const loadChatHistory = async () => {
  try {
    loading.value = true;
    console.log('Loading chat history...');
    const response = await axios.get('/api/ai/history');
    
    console.log('Chat history response:', response.data);
    
    if (response.data.success) {
      // 修复这里的映射，将 role 映射到 type，并处理文件URL
      messages.value = response.data.data.map(msg => {
        const messageObj = {
          type: msg.role, // 使用 role 字段作为 type
          content: msg.content,
          timestamp: new Date(msg.created_at)
        };
        
        // 如果消息包含文件URL，添加文件信息
        if (msg.file_url) {
          messageObj.file = {
            fileUrl: msg.file_url,
            fileType: msg.file_type || 'image', // 默认为图片类型
            fileName: msg.file_url.split('/').pop() // 从URL提取文件名
          };
        }
        
        return messageObj;
      });
      
      await nextTick(); // 等待DOM更新
      scrollToBottom();
    }
  } catch (error) {
    console.error('Error loading chat history:', error);
    ElMessage.error('无法加载聊天历史');
  } finally {
    loading.value = false;
  }
}

onMounted(() => {
  loadChatHistory();
  document.addEventListener('keydown', keydownHandler);
});

// 清理函数
onUnmounted(() => {
  messages.value = [];
  stopVoiceInput();
  document.removeEventListener('keydown', keydownHandler);
});

// 返回上一页
const router = useRouter()
const goBack = () => {
  router.go(-1)
}

// 语音输入
const startVoiceInput = () => {
  if (!('webkitSpeechRecognition' in window) && !('SpeechRecognition' in window)) {
    ElMessage.warning('您的浏览器不支持语音输入');
    return;
  }
  
  isRecording.value = true;
  
  // 使用标准SpeechRecognition或webkitSpeechRecognition
  const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
  recognition.value = new SpeechRecognition();
  recognition.value.lang = 'zh-CN';
  recognition.value.continuous = true;
  recognition.value.interimResults = true;
  
  recognition.value.onresult = (event) => {
    let finalTranscript = '';
    let interimTranscript = '';
    
    for (let i = event.resultIndex; i < event.results.length; i++) {
      const transcript = event.results[i][0].transcript;
      if (event.results[i].isFinal) {
        finalTranscript += transcript;
      } else {
        interimTranscript += transcript;
      }
    }
    
    // 更新输入框内容
    if (finalTranscript) {
      inputMessage.value = finalTranscript;
    } else if (interimTranscript) {
      inputMessage.value = interimTranscript;
    }
  };
  
  recognition.value.onend = () => {
    // 如果用户手动停止了录音，不要自动重新开始
    if (isRecording.value) {
      try {
        recognition.value.start();
      } catch (e) {
        console.error('无法重新启动语音识别:', e);
        stopVoiceInput();
      }
    }
  };
  
  recognition.value.onerror = (event) => {
    console.error('语音识别错误:', event.error);
    stopVoiceInput();
    ElMessage.error('语音识别出错，请重试');
  };
  
  try {
    recognition.value.start();
    ElMessage.success('语音输入已开启');
  } catch (e) {
    console.error('启动语音识别失败:', e);
    stopVoiceInput();
    ElMessage.error('无法启动语音识别');
  }
}

// 停止语音输入
const stopVoiceInput = () => {
  if (recognition.value) {
    isRecording.value = false;
    recognition.value.stop();
    recognition.value = null;
  }
}

// 退出语音输入
const exitVoiceInput = () => {
  stopVoiceInput();
  // 如果需要清空输入框，取消下面的注释
  // inputMessage.value = '';
}

// 发送消息的方法需要更新，以便在录音状态下也能正常发送
const sendMessageAndStopRecording = () => {
  // 如果正在录音，先停止录音
  if (isRecording.value) {
    stopVoiceInput();
  }
  // 然后发送消息
  sendMessage();
}

// 复制消息
const copyMessage = (content) => {
  navigator.clipboard.writeText(content);
  ElMessage.success('已复制到剪贴板');
}

// 导出聊天记录
const exportChat = () => {
  const text = messages.value
    .map(m => `${m.type === 'user' ? '我' : 'AI'}: ${m.content}`)
    .join('\n\n');
  
  const blob = new Blob([text], { type: 'text/plain' });
  const url = URL.createObjectURL(blob);
  const a = document.createElement('a');
  a.href = url;
  a.download = 'chat-history.txt';
  a.click();
  URL.revokeObjectURL(url);
}

// 重试发送失败的消息
const retryMessage = (index) => {
  const message = messages.value[index];
  if (message && message.type === 'user' && message.status === 'failed') {
    // 移除失败消息后面的所有消息
    messages.value = messages.value.slice(0, index);
    // 重新发送
    inputMessage.value = message.content;
    sendMessage();
  }
}

// 选择图片
const selectImage = async () => {
  // 创建一个隐藏的文件输入元素
  const fileInput = document.createElement('input')
  fileInput.type = 'file'
  fileInput.accept = 'image/*'
  fileInput.style.display = 'none'
  
  fileInput.onchange = async (event) => {
    const file = event.target.files[0]
    if (file) {
      imageFile.value = file
      
      // 创建预览URL
      if (imagePreviewUrl.value) {
        URL.revokeObjectURL(imagePreviewUrl.value)
      }
      imagePreviewUrl.value = URL.createObjectURL(file)
      
      // 显示已选择的文件名
      ElMessage.success(`已选择图片: ${file.name}`)
      
      // 上传图片到服务器
      await uploadImage(file)
    }
  }
  
  document.body.appendChild(fileInput)
  fileInput.click()
  document.body.removeChild(fileInput)
}

// 上传图片到服务器
const uploadImage = async (file) => {
  try {
    loading.value = true
    const result = await uploadToExternalService(file)
    
    if (result.success) {
      uploadedFileInfo.value = {
        fileUrl: result.fileUrl,
        fileName: result.fileName,
        fileType: 'image',
        localUrl: imagePreviewUrl.value
      }
      ElMessage.success('图片上传成功')
    } else {
      ElMessage.error(result.error || '图片上传失败')
    }
  } catch (error) {
    console.error('图片上传错误:', error)
    ElMessage.error('图片上传失败，请稍后重试')
  } finally {
    loading.value = false
  }
}

// 移除已选择的图片
const removeImage = () => {
  if (imagePreviewUrl.value) {
    URL.revokeObjectURL(imagePreviewUrl.value)
  }
  imageFile.value = null
  imagePreviewUrl.value = ''
  uploadedFileInfo.value = null
}

// 处理文件上传成功
const handleFileUploaded = (fileInfo) => {
  uploadedFileInfo.value = fileInfo
}

// 处理文件移除
const handleFileRemoved = () => {
  uploadedFileInfo.value = null
}

// 处理音频上传成功
const handleAudioUploaded = (fileInfo) => {
  uploadedFileInfo.value = fileInfo;
  showAudioRecorder.value = false;
  ElMessage.success('音频已准备好发送');
};

// 隐藏音频录制器
const hideAudioRecorder = () => {
  showAudioRecorder.value = false;
};

const keydownHandler = (event) => {
  // 如果正在录音，按ESC键退出
  if (isRecording.value) {
    if (event.key === 'Escape') {
      exitVoiceInput();
    } else if (event.key === 'Enter') {
      // 按Enter键发送消息并退出录音
      sendMessageAndStopRecording();
      event.preventDefault();
    }
  }
};

// 处理图片加载错误
const handleImageError = (file) => {
  console.error('图片加载失败:', file.fileUrl);
  ElMessage.warning('图片加载失败，请点击链接查看原文件');
};

// 处理音频加载错误
const handleAudioError = (file) => {
  console.error('音频加载失败:', file.fileUrl);
  ElMessage.warning('音频加载失败，请点击链接查看原文件');
};
</script>

<template>
  <div class="chat-container">
    <!-- 聊天头部 -->
    <div class="chat-header">
      <div class="header-content">
        <el-button 
          @click="goBack" 
          type="text" 
          class="back-button"
        >
          <el-icon><ArrowLeft /></el-icon>
          返回
        </el-button>
        <div class="title-container">
          <span class="title">AI 智能客服</span>
        </div>
      </div>
    </div>

    <!-- 聊天消息区域 -->
    <div class="chat-messages" ref="chatContainer">
      <el-empty
        v-if="messages.length === 0"
        description="暂无聊天记录"
      />
      
      <div 
        v-else
        v-for="(message, index) in messages" 
        :key="index"
        :class="['message', message.type]"
      >
        <div class="message-content">
          <template v-if="message.type === 'ai'">
            <img src="/ai-service.png" class="avatar" alt="AI Assistant" />
            <div class="text">{{ message.content }}</div>
          </template>
          <template v-else-if="message.type === 'user'">
            <img :src="userStore.avatar || '/default-avatar.png'" class="avatar" alt="User" />
            <div class="text">
              <!-- 如果消息包含文件，显示文件 -->
              <div v-if="message.file" class="message-file">
                <!-- 图片消息 -->
                <img 
                  v-if="message.file.fileType === 'image'" 
                  :src="message.file.localUrl || message.file.fileUrl" 
                  class="message-image" 
                  alt="用户发送的图片"
                  @error="handleImageError(message.file)"
                />
                <!-- 音频消息 -->
                <audio 
                  v-else-if="message.file.fileType === 'audio'" 
                  :src="message.file.localUrl || message.file.fileUrl" 
                  controls 
                  class="message-audio"
                  @error="handleAudioError(message.file)"
                ></audio>
                <div class="file-link">
                  <a :href="message.file.fileUrl" target="_blank">查看原文件</a>
                </div>
              </div>
              <!-- 显示消息文本 -->
              <div v-if="message.content">{{ message.content }}</div>
            </div>
          </template>
        </div>
        <div class="timestamp">
          <el-text type="info" size="small">
            {{ new Date(message.timestamp).toLocaleTimeString() }}
          </el-text>
        </div>
      </div>
      
      <div v-if="loading && !messages.some(m => m.isThinking)" class="loading-message">
        <el-icon class="is-loading"><Loading /></el-icon>
        <span>AI 正在思考...</span>
      </div>
    </div>
<!-- 
    聊天工具栏
    <div class="chat-toolbar">
      <el-button-group>
        <el-button @click="exportChat" icon="Download" type="info" plain>
          导出聊天记录
        </el-button>
      </el-button-group>
    </div> -->

    <!-- 聊天输入区域 -->
    <div class="chat-input">
      <div v-if="isRecording" class="voice-input-container">
        <div class="voice-input-icon-wrapper">
          <div class="voice-input-icon">
            <el-icon class="microphone-active"><Microphone /></el-icon>
          </div>
        </div>
        <div class="voice-input-tip">按 Esc 键退出语音输入</div>
        <div class="voice-input-text">{{ inputMessage }}</div>
        <div class="voice-input-actions">
          <el-button type="danger" plain @click="exitVoiceInput">退出</el-button>
          <el-button type="primary" @click="sendMessageAndStopRecording">发送</el-button>
        </div>
      </div>
      
      <div v-else-if="showAudioRecorder" class="audio-recorder-container">
        <div class="recorder-header">
          <h3>录制音频消息</h3>
          <el-button type="text" @click="hideAudioRecorder">
            <el-icon><Close /></el-icon>
          </el-button>
        </div>
        <AudioRecorder 
          @upload-success="handleAudioUploaded" 
          @upload-error="hideAudioRecorder"
          @remove="hideAudioRecorder"
        />
      </div>
      
      <div v-else class="input-area">
        <div class="input-wrapper">
          <!-- 图片预览区域 -->
          <div v-if="imagePreviewUrl" class="image-preview">
            <img :src="imagePreviewUrl" alt="预览图片" />
            <el-button
              type="danger"
              circle
              size="small"
              class="remove-image-btn"
              @click="removeImage"
            >
              <el-icon><Close /></el-icon>
            </el-button>
          </div>
          
          <!-- 音频预览区域 -->
          <div v-if="uploadedFileInfo && uploadedFileInfo.fileType === 'audio'" class="audio-preview">
            <audio 
              controls 
              :src="uploadedFileInfo.localUrl" 
              class="preview-audio"
            ></audio>
            <el-button
              type="danger"
              circle
              size="small"
              class="remove-audio-btn"
              @click="handleFileRemoved"
            >
              <el-icon><Close /></el-icon>
            </el-button>
          </div>
          
          <el-input
            v-model="inputMessage"
            type="textarea"
            :rows="3"
            :disabled="loading"
            placeholder="请输入消息..."
            @keyup.enter.exact.prevent="sendMessage"
          />
        </div>
        <div class="action-buttons">
          <el-dropdown trigger="click" class="tools-dropdown">
            <el-button circle>
              <el-icon><Plus /></el-icon>
            </el-button>
            <template #dropdown>
              <el-dropdown-menu>
                <el-dropdown-item @click="startVoiceInput">
                  <el-icon class="microphone"><Microphone /></el-icon>
                  <span>语音输入</span>
                </el-dropdown-item>
                <el-dropdown-item @click="showAudioRecorder = true">
                  <el-icon class="audio-recorder"><VideoCameraFilled /></el-icon>
                  <span>录制音频</span>
                </el-dropdown-item>
                <el-dropdown-item @click="selectImage">
                  <el-icon class="picture"><Picture /></el-icon>
                  <span>选择图片</span>
                </el-dropdown-item>
                <el-dropdown-item @click="exportChat">
                  <el-icon class="download"><Download /></el-icon>
                  <span>导出记录</span>
                </el-dropdown-item>
              </el-dropdown-menu>
            </template>
          </el-dropdown>
          
          <el-button 
            type="primary" 
            :loading="loading"
            @click="sendMessage"
            class="send-button"
          >
            发送
          </el-button>
        </div>
      </div>
    </div>
  </div>
</template>

<style scoped>
.chat-container {
  display: flex;
  flex-direction: column;
  height: calc(100vh - 40px);
  max-width: 1200px;
  margin: 20px auto;
  background: #FFFFFF;
  border-radius: 24px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.06);
  overflow: hidden;
}

/* 移除装饰性背景元素 */
.chat-container::before {
  content: none;
}

.chat-header {
  padding: 16px 24px;
  background: #FFFFFF;
  color: #333333;
  border-bottom: 1px solid rgba(0, 0, 0, 0.06);
  display: flex;
  align-items: center;
  justify-content: center;
}

.header-content {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
}

.back-button {
  position: absolute;
  left: 0;
  color: #666;
  display: flex;
  align-items: center;
  font-size: 14px;
}

.back-button i {
  margin-right: 4px;
}

.title-container {
  display: flex;
  align-items: center;
  justify-content: center;
}

.title {
  font-size: 18px;
  font-weight: 600;
  color: #333333;
}

.chat-messages {
  flex: 1;
  overflow-y: auto;
  padding: 32px;
  display: flex;
  flex-direction: column;
  gap: 30px;
  background-color: #FFFFFF;
}

/* 美化滚动条 */
.chat-messages::-webkit-scrollbar {
  width: 8px;
}

.chat-messages::-webkit-scrollbar-thumb {
  background: rgba(0, 0, 0, 0.1);
  border-radius: 4px;
}

.chat-messages::-webkit-scrollbar-track {
  background: rgba(255, 255, 255, 0.1);
}

.message {
  display: flex;
  flex-direction: column;
  max-width: 80%;
  animation: fadeIn 0.3s ease-out;
}

@keyframes fadeIn {
  from { opacity: 0; transform: translateY(10px); }
  to { opacity: 1; transform: translateY(0); }
}

.message.user {
  align-self: flex-end;
}

.message.ai {
  align-self: flex-start;
}

.message.system {
  align-self: center;
  max-width: 90%;
}

.message-content {
  display: flex;
  gap: 16px;
  align-items: flex-start;
}

.message.user .message-content {
  flex-direction: row-reverse;
}

/* 头像样式 */
.avatar {
  width: 45px;
  height: 45px;
  border-radius: 50%;
  object-fit: cover;
  flex-shrink: 0;
  border: 2px solid #fff;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
  transition: transform 0.3s ease;
}

.message.user .avatar {
  border-color: #E6E6E6;
}

.message.ai .avatar {
  border-color: #4E6FFF;
}

.avatar:hover {
  transform: scale(1.05) rotate(5deg);
}

.text {
  padding: 16px 20px;
  border-radius: 18px;
  position: relative;
  word-break: break-word;
  white-space: pre-wrap;
  font-size: 15px;
  line-height: 1.6;
  /* max-width: calc(100% - 80px); */
}

.message.user .text {
  background: #4E6FFF;
  color: white;
  border-top-right-radius: 4px;
  margin-left: auto;
}

.message.ai .text {
  background: #F7F8FA;
  border-top-left-radius: 4px;
  color: #333;
  border: 1px solid #EEEEEE;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.03);
  margin-right: auto;
}

.message.system .text {
  background: #f0f2f5;
  border-radius: 12px;
  font-style: italic;
  color: #606266;
  text-align: center;
  max-width: 100%;
  padding: 12px 24px;
}

.timestamp {
  font-size: 12px;
  color: #999;
  margin-top: 8px;
  padding: 0 12px;
}

.message.user .timestamp {
  text-align: right;
}

.message.ai .timestamp {
  text-align: left;
}

.chat-toolbar {
  padding: 12px 20px;
  display: flex;
  justify-content: flex-end;
  gap: 12px;
  background: white;
  border-top: 1px solid var(--el-border-color-lighter);
}

.chat-input {
  padding: 15px 40px 0 40px;
  background: #FFFFFF;
  border-top: 1px solid rgba(0, 0, 0, 0.06);
}

.input-area {
  display: flex;
  gap: 12px;
  margin-bottom: 12px;
}

.input-wrapper {
  flex: 1;
  position: relative;
  display: flex;
  flex-direction: column;
}

.image-preview {
  position: relative;
  margin-bottom: 12px;
  border-radius: 12px;
  overflow: hidden;
  max-width: 200px;
  max-height: 150px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
  border: 1px solid #EEEEEE;
}

.image-preview img {
  width: 100%;
  height: auto;
  display: block;
  object-fit: cover;
  max-height: 150px;
}

.remove-image-btn {
  position: absolute;
  top: 8px;
  right: 8px;
  opacity: 0.8;
  backdrop-filter: blur(2px);
  background-color: rgba(255, 255, 255, 0.6) !important;
  border: none !important;
  transition: all 0.2s ease;
}

.remove-image-btn:hover {
  opacity: 1;
  background-color: rgba(255, 255, 255, 0.8) !important;
  transform: scale(1.1);
}

.action-buttons {
  display: flex;
  flex-direction: column;
  gap: 8px;
  justify-content: flex-end;
}

.tools-dropdown {
  margin-bottom: 4px;
}

.send-button {
  height: 40px;
  padding: 0 20px;
  background: #4E6FFF !important;
  border: none !important;
  font-weight: 500;
  transition: all 0.3s ease !important;
}

.send-button:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(78, 111, 255, 0.2);
  opacity: 0.9;
}

.send-button:active {
  transform: translateY(0);
  box-shadow: 0 2px 6px rgba(78, 111, 255, 0.1);
}

.send-button.is-loading {
  background: rgba(78, 111, 255, 0.8) !important;
  opacity: 0.8;
}

:deep(.el-textarea__inner) {
  border-radius: 16px;
  padding: 12px 16px;
  resize: none;
  min-height: 60px !important;
  font-size: 15px;
  border: 1px solid #EEEEEE;
  background: #FFFFFF;
  transition: all 0.3s ease;
}

:deep(.el-textarea__inner:focus) {
  border-color: #4E6FFF;
  box-shadow: 0 0 0 3px rgba(78, 111, 255, 0.1);
}

.thinking {
  opacity: 0.7;
  font-style: italic;
}

.sending-status {
  font-size: 12px;
  color: var(--el-text-color-secondary);
  margin-top: 4px;
  display: flex;
  align-items: center;
  gap: 4px;
}

.sending-status.error {
  color: var(--el-color-danger);
}

.is-loading {
  animation: rotating 2s linear infinite;
}

@keyframes rotating {
  from { transform: rotate(0deg); }
  to { transform: rotate(360deg); }
}

.loading-message {
  padding: 12px 24px;
  background: rgba(255, 255, 255, 0.9);
  border-radius: 20px;
  font-size: 14px;
  color: #4E6FFF;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.04);
}

/* 适配移动端 */
@media screen and (max-width: 768px) {
  .chat-container {
    height: 100vh;
    margin: 0;
    border-radius: 0;
  }
  
  .chat-messages {
    padding: 16px;
  }
  
  .message {
    max-width: 85%;
  }
  
  .chat-input {
    padding: 16px;
  }
  
  :deep(.el-textarea__inner) {
    min-height: 50px !important;
  }
  
  .action-buttons {
    gap: 6px;
  }
  
  .send-button {
    height: 36px;
    padding: 0 16px;
  }
}

/* 工具下拉菜单样式 */
.tools-dropdown {
  margin-bottom: 4px;
}

:deep(.el-dropdown-menu__item) {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 16px;
  cursor: pointer;
  transition: all 0.2s ease;
}

:deep(.el-dropdown-menu__item:hover) {
  background-color: rgba(255, 182, 193, 0.1);
}

:deep(.el-dropdown-menu__item .el-icon) {
  margin-right: 4px;
  font-size: 16px;
  color: #FFB6C1;
}

:deep(.el-button.is-circle) {
  width: 40px;
  height: 40px;
  padding: 8px;
  background: rgba(78, 111, 255, 0.05);
  border-color: rgba(78, 111, 255, 0.1);
  color: #4E6FFF;
  transition: all 0.3s ease;
}

:deep(.el-button.is-circle:hover) {
  background: rgba(78, 111, 255, 0.1);
  transform: rotate(90deg);
}

:deep(.el-dropdown-menu) {
  padding: 4px;
  min-width: 120px;
  border: 1px solid #EEEEEE;
  border-radius: 8px;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);
}

/* 调整下拉菜单选项的图标 */
:deep(.el-dropdown-menu__item .el-icon.microphone),
:deep(.el-dropdown-menu__item .el-icon.picture),
:deep(.el-dropdown-menu__item .el-icon.download),
:deep(.el-dropdown-menu__item .el-icon.audio-recorder) {
  color: #4E6FFF;
}

/* 语音输入样式 */
.voice-input-container {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 20px;
  background: #FFFFFF;
  border-radius: 16px;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.06);
  margin: 0 20px 16px 20px;
  min-height: 200px;
}

.voice-input-icon-wrapper {
  margin-bottom: 20px;
  position: relative;
  width: 120px;
  height: 120px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.voice-input-icon-wrapper::before {
  content: '';
  position: absolute;
  width: 100%;
  height: 100%;
  border-radius: 50%;
  background-color: rgba(0, 149, 255, 0.1);
  animation: pulse 1.5s infinite;
}

.voice-input-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 80px;
  height: 80px;
  border-radius: 50%;
  background-color: #4E6FFF;
  box-shadow: 0 4px 12px rgba(78, 111, 255, 0.2);
}

.microphone-active {
  font-size: 36px;
  color: white;
}

.pulse {
  animation: pulse 1.5s infinite;
}

@keyframes pulse {
  0% {
    box-shadow: 0 0 0 0 rgba(0, 149, 255, 0.4);
    transform: scale(0.95);
  }
  70% {
    box-shadow: 0 0 0 20px rgba(0, 149, 255, 0);
    transform: scale(1);
  }
  100% {
    box-shadow: 0 0 0 0 rgba(0, 149, 255, 0);
    transform: scale(0.95);
  }
}

.voice-input-tip {
  font-size: 14px;
  color: #999;
  margin-bottom: 8px;
}

.voice-input-text {
  font-size: 18px;
  margin-bottom: 20px;
  text-align: center;
  color: #333;
  max-width: 80%;
  min-height: 24px;
  font-weight: 500;
  word-break: break-word;
}

.voice-input-actions {
  display: flex;
  gap: 16px;
  margin-top: 10px;
}

/* 移动设备适配 */
@media screen and (max-width: 768px) {
  .voice-input-container {
    margin: 0 10px 10px 10px;
    padding: 15px;
    min-height: 160px;
  }
  
  .voice-input-icon-wrapper {
    width: 90px;
    height: 90px;
    margin-bottom: 15px;
  }
  
  .voice-input-icon {
    width: 60px;
    height: 60px;
  }
  
  .microphone-active {
    font-size: 28px;
  }
  
  .voice-input-text {
    font-size: 16px;
    margin-bottom: 15px;
  }
  
  .voice-input-actions {
    gap: 10px;
  }
}

/* 消息文件样式 */
.message-file {
  margin-bottom: 10px;
}

.message-image {
  max-width: 100%;
  max-height: 200px;
  border-radius: 8px;
  margin-bottom: 8px;
}

.message-audio {
  width: 100%;
  margin-bottom: 8px;
}

.file-link {
  font-size: 12px;
  margin-top: 4px;
}

.file-link a {
  color: #1989fa;
  text-decoration: none;
}

.file-link a:hover {
  text-decoration: underline;
}

/* 音频录制器容器 */
.audio-recorder-container {
  background-color: white;
  border-radius: 16px;
  padding: 15px;
  box-shadow: 0 0 15px rgba(0, 0, 0, 0.1);
  margin-bottom: 16px;
}

.recorder-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 15px;
  border-bottom: 1px solid #eee;
  padding-bottom: 10px;
}

.recorder-header h3 {
  margin: 0;
  font-size: 16px;
  color: #333;
}

/* 音频预览样式 */
.audio-preview {
  position: relative;
  margin-bottom: 12px;
  padding: 10px;
  border-radius: 12px;
  background-color: rgba(78, 111, 255, 0.05);
  border: 1px solid #EEEEEE;
}

.preview-audio {
  width: 100%;
}

.remove-audio-btn {
  position: absolute;
  top: 8px;
  right: 8px;
  opacity: 0.8;
  backdrop-filter: blur(2px);
  background-color: rgba(255, 255, 255, 0.6) !important;
  border: none !important;
  transition: all 0.2s ease;
}

.remove-audio-btn:hover {
  opacity: 1;
  background-color: rgba(255, 255, 255, 0.8) !important;
  transform: scale(1.1);
}

/* 下拉菜单图标样式 */
:deep(.el-dropdown-menu__item .el-icon.audio-recorder) {
  color: #4E6FFF;
}
</style> 